package com.mlnx.work.controller;

import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mlnx.common.entity.Response;
import com.mlnx.common.entity.ResponseData;
import com.mlnx.common.utils.MyLog;
import com.mlnx.work.entity.ProjectDir;
import com.mlnx.work.entity.ProjectTask;
import com.mlnx.work.entity.User;
import com.mlnx.work.enums.ProjectStatusEnum;
import com.mlnx.work.enums.ProjectTypeEnum;
import com.mlnx.work.enums.ResponseEnum;
import com.mlnx.work.exception.WorkServiceException;
import com.mlnx.work.pojo.form.ProjectForm;
import com.mlnx.work.pojo.form.TaskForm;
import com.mlnx.work.pojo.form.UploadTaskForm;
import com.mlnx.work.pojo.vo.*;
import com.mlnx.work.service.ProjectDirService;
import com.mlnx.work.service.ProjectMemberService;
import com.mlnx.work.service.ProjectTaskService;
import com.mlnx.work.service.UserService;
import com.mlnx.work.utils.ExcelFileUtil;
import com.xuxueli.poi.excel.ExcelExportUtil;
import com.xuxueli.poi.excel.ExcelImportUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import jdk.nashorn.internal.parser.Token;
import org.apache.http.protocol.ResponseDate;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.shan.spring.base.BaseController;
import org.shan.spring.base.annotations.SysLog;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

//import com.xuxueli.poi.excel.ExcelExportUtil;
//import com.xuxueli.poi.excel.ExcelImportUtil;

/**
 * @Author: Akrio
 * @Date: 2021-01-26 14:05
 */
@SysLog(title = "任务上传")
@Api(value = "上传接口", tags = {"上传接口"})
@RestController
@RequestMapping("/uploading")
public class UploadingController extends BaseController {

    @Autowired
    private ProjectDirService projectDirService;
    @Autowired
    private UserService userService;
    @Autowired
    private ProjectMemberService projectMemberService;
    @Autowired
    private ProjectController projectController;
    @Autowired
    private TaskController taskController;
    @Autowired
    private ProjectTaskService projectTaskService;


    @ApiOperation("上传任务")
    @PostMapping("/task")
    @Transactional
    public Response upload(@RequestParam("file") MultipartFile file, Integer creatorId, Token token) {
        Map<String, Integer> kv = new HashMap<>();
        List<Map<String, String>> maps = ExcelFileUtil.analysisExcel(file);  //解析Excel
        for (Map<String, String> map : maps) {
            UploadTaskForm uploadTaskForms = JSON.parseObject(JSON.toJSONString(map), UploadTaskForm.class);
            if(uploadTaskForms.getType()!=null && !("".equals(uploadTaskForms.getType()))){        //判断类别  项目
                if (uploadTaskForms.getId() == null) {   //添加项目
                    System.out.println("开始添加项目");
                    System.out.println(uploadTaskForms);
                    if ("任务".equals(uploadTaskForms.getType()) || "子任务".equals(uploadTaskForms.getType())) {
                        addTask(uploadTaskForms, kv);
                    }else {
                        addProject(uploadTaskForms, kv, creatorId);
                    }
                } else {//更新
                    if ("任务".equals(uploadTaskForms.getType()) || "子任务".equals(uploadTaskForms.getType())) {
                        updateTask(uploadTaskForms,kv);
                    }else {
                        updateProject(uploadTaskForms,kv);
                    }
                }
            }
        }
        return result();
    }

    @ApiOperation("生成Excel")
    @GetMapping("createExcel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "项目id", required = true)
    })
    public void createExcel(HttpServletResponse response, Integer projectId) {
        Map<String, String> kv = new HashMap<>();
        List<UploadTaskVO> uploadTaskVOS = new ArrayList<>();
        ProjectTaskVO projectTask = projectDirService.getProjectTaskByDirId(projectId);
//        System.out.println(projectTask);
        String rootNo = "1";
        String[] item = {"编号","类别","名称","状态","开始时间","结束时间","实际开始时间","实际完成时间","逾期拟完成时间","逾期比","逾期次数","工时","风险项","交付物","标签","里程碑","负责人","所属单机","唯一标识"};
        projectTask.setItemNo(rootNo);
        copyProject(uploadTaskVOS,projectTask,kv);
        createItemNo(rootNo,projectTask.getChildProjectTaskVO(),projectTask.getTaskVOS(),uploadTaskVOS,kv);

        byte[] bytes = ExcelFileUtil.createExcel(uploadTaskVOS, item);
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition",
                "attachment;fileName=" + "Excel.xls");
        response.setContentLength((bytes.length));
        try {
            OutputStream os = response.getOutputStream();
            os.write(bytes, 0, bytes.length);
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


//        List<UploadTaskForm> uploadTaskFormList = new ArrayList<>();
//        List<UploadTaskVO> uploadTaskVOS = new ArrayList<>();
//        ProjectTaskVO projectTask = projectDirService.getProjectTaskByDirId(projectId);
//        String rootNo = "1";
//        projectTask.setItemNo(rootNo);
//        copyProject(uploadTaskVOS,projectTask);
//        createItemNo(rootNo,projectTask.getChildProjectTaskVO(),projectTask.getTaskVOS(),uploadTaskVOS);
//
////        ExcelExportUtil.exportToFile(uploadTaskFormList, "D:\\testFile\\workbook.xls");
////        System.out.println(JSON.toJSONString(uploadTaskFormList));
//        byte[] bytes = ExcelExportUtil.exportToBytes(uploadTaskVOS);
//
//
//        response.setCharacterEncoding("utf-8");
//        response.setContentType("multipart/form-data");
//        response.setHeader("Content-Disposition",
//                "attachment;fileName=" + "workbook.xls");
//        response.setContentLength((bytes.length));
//
//        try {
//            OutputStream os = response.getOutputStream();
//            os.write(bytes, 0, bytes.length);
//            os.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }


    }


    private void copyProject(List<UploadTaskVO> uploadTaskFormList, ProjectTaskVO projectDir,Map<String, String> kv) {
        UploadTaskVO uploadTaskForm = new UploadTaskVO();
        uploadTaskForm.setItemNo(projectDir.getItemNo());       //设置编号
        uploadTaskForm.setId(projectDir.getDirId()); //设置id
        uploadTaskForm.setType(projectDir.getType());           //设置类型
        uploadTaskForm.setName(projectDir.getDirName());//设置名称
        uploadTaskForm.setStatus(projectDir.getStatus());      //设置状态
        uploadTaskForm.setOriginEndTime(projectDir.getOriginEndTime());   //设置计划结束时间
        uploadTaskForm.setOriginStartTime(projectDir.getOriginStartTime());   //设置计划开始时间
        uploadTaskForm.setStartTime(projectDir.getStartTime());       //设置实际开始时间
        uploadTaskForm.setCompletedTime(projectDir.getCompletedTime());//设置实际完成时间
        uploadTaskForm.setOverdueTime(projectDir.getOverdueTime());      //设置计划预期时间
        uploadTaskForm.setOverdueRate(projectDir.getOverdueRate());      //设置逾期率
        uploadTaskForm.setOverdueTimes(projectDir.getOverdueTimes());    //预期次数
        uploadTaskForm.setTags(projectDir.getTags());        //设置标签
        uploadTaskForm.setRisk(projectDir.getRisk());        //设置风险项
        uploadTaskForm.setAchievement(projectDir.getAchievement());//设置交付物
        uploadTaskForm.setMilepost(projectDir.getMilepost() ? 1 : 0);    //设置里程碑
        uploadTaskForm.setManager(projectDir.getManager());
        List<MemberVO> memberById = projectDirService.getMemberById(projectDir.getDirId());

        StringBuilder members = new StringBuilder();
        for (int i = 0; i < memberById.size(); i++) {
            if (memberById.get(i) == null) {
                break;
            }
            if (i == memberById.size() - 1) {
                members.append(memberById.get(i).getMemberName());
            } else {
                members.append(memberById.get(i).getMemberName()).append("&");
            }
        }
        uploadTaskForm.setMember(members.toString());
        uploadTaskFormList.add(uploadTaskForm);
        kv.put(projectDir.getItemNo(),uploadTaskForm.getName());      //保存对应关系
    }

    private void copyTask(List<UploadTaskVO> uploadTaskFormList, TaskVO projectTask,Map<String, String> kv) {
        UploadTaskVO uploadTaskForm = new UploadTaskVO();
        uploadTaskForm.setItemNo(projectTask.getItemNo());       //设置编号
        uploadTaskForm.setId(projectTask.getTaskId()); //设置id
        uploadTaskForm.setType(projectTask.getType());           //设置类别
        String itemNo = projectTask.getItemNo();
        if("子任务".equals(projectTask.getType())){
            uploadTaskForm.setParent(kv.get( itemNo.substring(0, itemNo.length() - 4) ));
        }else {
            uploadTaskForm.setParent(kv.get( itemNo.substring(0, itemNo.length() - 2) ));
        }
        uploadTaskForm.setName(projectTask.getTaskName());//设置名称
        uploadTaskForm.setStatus(projectTask.getStatus());      //设置状态
        uploadTaskForm.setOriginEndTime(projectTask.getOriginEndTime());   //设置计划结束时间
        uploadTaskForm.setOriginStartTime(projectTask.getOriginStartTime());   //设置计划开始时间
        uploadTaskForm.setStartTime(projectTask.getStartTime());       //设置实际开始时间
        uploadTaskForm.setCompletedTime(projectTask.getCompletedTime());//设置实际完成时间
        uploadTaskForm.setOverdueTime(projectTask.getOverdueTime());      //设置计划预期时间
        uploadTaskForm.setOverdueRate(projectTask.getOverdueRate());      //设置逾期率
        uploadTaskForm.setOverdueTimes(projectTask.getOverdueTimes());    //预期次数
        uploadTaskForm.setWorkHour(projectTask.getWorkHour());      //设置工时
        uploadTaskForm.setTags(projectTask.getTags());        //设置标签
        uploadTaskForm.setRisk(projectTask.getRisk());        //设置风险项
        uploadTaskForm.setAchievement(projectTask.getAchievement());//设置交付物
        uploadTaskForm.setMilepost(projectTask.getMilepost() ? 1 : 0);    //设置里程碑
        uploadTaskForm.setManager(projectTask.getManager());
        uploadTaskFormList.add(uploadTaskForm);
    }


    private void addProject(UploadTaskForm uploadTaskForms, Map<String, Integer> kv, Integer id) {

        ProjectForm projectForm = new ProjectForm();
        String[] serial = uploadTaskForms.getItemNo().split("\\.");             //项目层级序列
        String s1 = uploadTaskForms.getItemNo().replaceAll("\\.", "");//所有层级
        int managerIdByName = getManagerIdByName(uploadTaskForms.getManager());     //获取负责人ID
        int count = serial.length;
        if (count == 1) {//说明是根项目
            projectForm.setRootId(0);
            projectForm.setCreatorId(id);                           //设置创建人id
            projectForm.setParentId(0);
        } else {
            String substring = s1.substring(0, s1.length() - 1);   //获取上一级目录
            projectForm.setRootId(kv.get(serial[0]));
            projectForm.setParentId(kv.get(substring));             //获取上一级目录ID
            projectForm.setCreatorId(managerIdByName);                           //设置创建人id
        }
        projectForm.setDirName(uploadTaskForms.getName());
        BeanUtils.copyProperties(uploadTaskForms, projectForm);
        projectForm.setMilepost(uploadTaskForms.getMilepost() != 0);
        projectForm.setManagerId(managerIdByName);                  //设置负责人ID
        projectForm.setType(ProjectTypeEnum.getCode(uploadTaskForms.getType()));
        Integer[] memberIdByName = getMemberIdByName(uploadTaskForms.getManager(), managerIdByName);    //获取所有成员ID，包括负责人
        projectForm.setMemberIds(memberIdByName);
        System.out.println(projectForm);
        ResponseData projectDir = (ResponseData)projectController.createProjectDir(projectForm);//返回目录id 1
        kv.put(s1, (Integer)projectDir.getObj());        //保存层级对应关系
    }

    private void addTask(UploadTaskForm uploadTaskForms, Map<String, Integer> kv) {
        TaskForm taskForm = new TaskForm();
        int managerIdByName = getManagerIdByName(uploadTaskForms.getManager());
        String s1 = uploadTaskForms.getItemNo().replaceAll("\\.", "");//所有层级
        BeanUtils.copyProperties(uploadTaskForms, taskForm);    //复制task类
        taskForm.setTaskName(uploadTaskForms.getName());        //设置名称
        String substring1 = s1.substring(0, s1.length() - 1);   //获取上一级目录
        String substring2 = s1.substring(0, s1.length() - 2);   //获取上一级目录
        if("子任务".equals(uploadTaskForms.getType())){       //子任务
            taskForm.setParentId(kv.get(substring1));
            taskForm.setDirId(kv.get(substring2));
        }else {
            taskForm.setParentId(0);
            taskForm.setDirId(kv.get(substring1));             //获取上一级目录ID
        }
        taskForm.setCreatorId(managerIdByName);                           //设置创建人id
        taskForm.setMilepost(uploadTaskForms.getMilepost() != 0);
        taskForm.setManagerId(managerIdByName);
        taskForm.setTransferDeptId(0);
        taskForm.setDescription("");
        taskForm.setType(ProjectTypeEnum.getCode(uploadTaskForms.getType()));
        ResponseData projectTask = (ResponseData)taskController.createProjectTask(taskForm);//返回目录id 1
        kv.put(s1, (Integer)projectTask.getObj());        //保存层级对应关系
    }

    private int getManagerIdByName(String name) {
        List<User> users = userService.list(new QueryWrapper<User>().eq("name", name));
        if (users.size() == 0)
            throw new WorkServiceException(ResponseEnum.PARAM_ERROR);
        return users.get(0).getId();
    }

    private Integer[] getMemberIdByName(String names, Integer managerId) {
        String member[] = names.split("&");        //按&拆封人员
        Integer[] num = new Integer[member.length + 1];
        num[0] = managerId;                    //设置负责人
        for (int i = 0; i < member.length; i++) {
            List<User> name = userService.list(new QueryWrapper<User>().eq("name", member[i]));
            if (name.size() == 0)
                throw new WorkServiceException(ResponseEnum.PARAM_ERROR);
            num[++i] = name.get(0).getId();             //设置每个成员的ID
        }
        return num;
    }

    private void updateProject(UploadTaskForm uploadTaskForms, Map<String, Integer> kv){
        //判断类别  项目更新
        int managerIdByName = getManagerIdByName(uploadTaskForms.getManager());
        ProjectDir projectDir = projectDirService.getById(uploadTaskForms.getId());
        kv.put(uploadTaskForms.getItemNo().replaceAll("\\.", ""),projectDir.getId());
        ProjectDir pd = new ProjectDir();
        pd.setId(uploadTaskForms.getId());
        if (projectDir.getManagerId() != managerIdByName)
            throw new WorkServiceException(ResponseEnum.NONE_PROJECT_AUTHORITY);
        if(projectDir.getStartTime()==0 && uploadTaskForms.getStartTime() != null)      //数据库没有时间并且填写了时间
            pd.setStartTime(uploadTaskForms.getStartTime());
//                    if (uploadTaskForms.getStartTime() != null && uploadTaskForms.getStartTime()!=projectDir.getStartTime()) {           //完成时间不为空且
//                        if (projectDir.getStartTime() > 0)
//                            throw new WorkServiceException(ResponseEnum.START_TIME_SET_ALREADY);
//                        pd.setStartTime(projectDir.getStartTime());
//                    }
        if (uploadTaskForms.getCompletedTime() != null && projectDir.getCompletedTime()==0) {
            pd.setCompletedTime(uploadTaskForms.getCompletedTime());
            if(uploadTaskForms.getCompletedTime()<System.currentTimeMillis())
                pd.setStatus(ProjectStatusEnum.DONE_VERIFY);
        }
        if (uploadTaskForms.getRisk() != null) {
            pd.setRisk(uploadTaskForms.getRisk());
        }
        projectDirService.updateById(pd);

    }
    private void updateTask(UploadTaskForm uploadTaskForms, Map<String, Integer> kv){
        //任务更新
        ProjectTask projectTask = projectTaskService.getById(uploadTaskForms.getId());
        kv.put(uploadTaskForms.getItemNo().replaceAll("\\.", ""),projectTask.getId());
        ProjectTask pt = new ProjectTask();
        pt.setId(uploadTaskForms.getId());
        int managerIdByName = getManagerIdByName(uploadTaskForms.getManager());
        if (projectTask.getManagerId() != managerIdByName)
            throw new WorkServiceException(ResponseEnum.NONE_PROJECT_AUTHORITY);
        if (uploadTaskForms.getStartTime() != null  && projectTask.getStartTime()==0) {           //完成时间不为空且
            if (projectTask.getStartTime() > 0)
                throw new WorkServiceException(ResponseEnum.START_TIME_SET_ALREADY);
            pt.setStartTime(uploadTaskForms.getStartTime());
        }
        if (projectTask.getCompletedTime() != null && projectTask.getCompletedTime()==0) {
//                        if (projectTask.getCompletedTime() > 0)
//                            throw new WorkServiceException(ResponseEnum.START_TIME_SET_ALREADY);    //已设置完成时间
            //检查子任务是否全部完成
//                        List<ProjectTask> childTasks = projectTaskService.getByParentId(uploadTaskForms.getId());
//                        boolean allCompleted = true;
//                        for (ProjectTask childTask : childTasks) {
//                            if (!childTask.getStatus().equals(ProjectStatusEnum.DONE)) {
//                                allCompleted = false;
//                                break;
//                            }
//                        }
//                        if (!allCompleted) {
//                            throw new WorkServiceException(ResponseEnum.CHILD_NOT_COMPLETED);
//                        }
            pt.setStatus(ProjectStatusEnum.DONE_VERIFY);
        }
        if (uploadTaskForms.getWorkHour() != null)
            pt.setWorkHour(uploadTaskForms.getWorkHour());
        if (uploadTaskForms.getRisk() != null) {
            pt.setRisk(uploadTaskForms.getRisk());
        }
        projectTaskService.updateById(pt);

    }



    /**
     * 递归设置项目编号
     *
     * @param rootNo
     * @param childProjectTaskVOS
     */
    private void createItemNo(String rootNo, List<ProjectTaskVO> childProjectTaskVOS, List<TaskVO> childTaskVOS,List<UploadTaskVO> uploadTaskFormList,Map<String, String> kv) {
        int begin = 1;
        if (childProjectTaskVOS != null)
            for (ProjectTaskVO childProjectTaskVO : childProjectTaskVOS) {
                String itemNo = rootNo + "." + begin;
                childProjectTaskVO.setItemNo(itemNo);
                copyProject(uploadTaskFormList,childProjectTaskVO,kv);
                if (childProjectTaskVO.getChildProjectTaskVO() != null)
                    createItemNo(itemNo, childProjectTaskVO.getChildProjectTaskVO(), childProjectTaskVO.getTaskVOS(),uploadTaskFormList,kv);
                begin++;
            }

        if (childTaskVOS != null)
            for (TaskVO childTaskVO : childTaskVOS) {
                String itemNo = rootNo + "." + begin;
                childTaskVO.setItemNo(itemNo);
                copyTask(uploadTaskFormList,childTaskVO,kv);
                if (childTaskVO.getChildTaskVO() != null)
                    createItemNo(itemNo, null, childTaskVO.getChildTaskVO(),uploadTaskFormList,kv);
                begin++;
            }
    }

}
